package com.ai.web.schedule;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimerTask;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

import com.ai.web.app.AndroidPushNotification;
import com.ai.web.app.IosPushNotification;
import com.ai.web.cache.Constants;
import com.ai.web.service.AppPushLogService;
import com.ai.web.service.AppUserService;
import com.ai.web.service.CommentRepairService;
import com.ai.web.service.RepairService;
import com.ai.web.service.WxUserService;
import com.ai.web.util.Utils;
import com.ai.web.util.WorkStatus;
import com.ai.web.vo.AppPushLogV;
import com.ai.web.vo.AppUserV;
import com.ai.web.vo.RepairV;
import com.ai.web.vo.ResultModel;
import com.ai.web.vo.WxUserV;

public class WorkOrdersTimerTask  extends TimerTask {
	private static Logger logger = Logger.getLogger(WorkOrdersTimerTask.class);
	//1分钟之后自动派发
	private static final long POSTPONE = 1 * 60 * 1000;
	@Autowired
    private RepairService repairService;
    @Autowired
    private WxUserService wxUserService;
    @Autowired
    private AppUserService appUserService;
    @Autowired
    private AppPushLogService appPushLogService;
    @Autowired
    private CommentRepairService commentRepairService;
    
	public WorkOrdersTimerTask() {
		WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
		repairService = (RepairService)context.getBean("repairService");
		wxUserService = (WxUserService)context.getBean("wxUserService");
		appUserService = (AppUserService)context.getBean("appUserService");
		appPushLogService = (AppPushLogService)context.getBean("appPushLogService");
		commentRepairService = (CommentRepairService)context.getBean("commentRepairService");
	}
	@Override
	public void run() {
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		//logger.info("WorkOrdersTimerTask......................................"+sdf.format(new Date()));	
		try {
			RepairV repairV = WorkOrdersQueue.poll();
			//拿不到记录
			if(repairV==null) {
				//logger.info("WorkOrdersTimerTask......................................记录为空");
				return;
			}else {
				//logger.info("WorkOrdersTimerTask......................................拿到记录了");
			}
			RepairV repair = repairService.getRepair(repairV.getId());
			Date createTime = repairV.getCreateTime();
			if(logger.isDebugEnabled()) {
				logger.debug("多长时间自动派发："+POSTPONE/1000+",now is "+sdf.format(new Date())+",工单生成时间："+sdf.format(createTime)
						+",还差多长时间自动派发："+( ((new Date()).getTime()-createTime.getTime())  )/1000   );
			}
			if(((new Date()).getTime()-createTime.getTime()) < POSTPONE) {
				//放回去队列，直接等待
				WorkOrdersQueue.offer(repairV);
				return;
			}
 			//维护人员的手机
			String maintenancePhone = repairV.getMaintenancePhone();
			if(maintenancePhone==null || appUserService.getAppUserByPhone(maintenancePhone) == null || repair.getStatus()!=WorkStatus.NEW.getValue()) {
				if(logger.isDebugEnabled())
				logger.debug("状态处于{维护人员手机为空,根据手机号码找不到维护人员,状态不是未派发}，直接放弃自动下发");
				return;
			}
			if(logger.isDebugEnabled()) {
				logger.debug("now time is "+(new Date()).getTime());
				logger.debug("createTime is "+createTime.getTime());
				logger.debug("时间差是"+((new Date()).getTime()-createTime.getTime())/1000);
			}
			
			synchronized(this) {
				repair = repairService.getRepair(repairV.getId());
				if(logger.isDebugEnabled()) {
					logger.debug("工单生成时间:"+sdf.format(createTime)+",工单状态:"+repairV.getStatus());	
				}
				//如果状态不是未派发，直接丢弃
				if(repair.getStatus()==WorkStatus.NEW.getValue()) {
					//下发工单
					sendWorkOrders(repair);
				}
			}
		
			
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		logger.info("end");
		
	}
	/**
	 * 下发工单
	 * @param repairV
	 * @throws Exception
	 * @throws InterruptedException
	 */
	private void sendWorkOrders(RepairV repairV) throws Exception,
			InterruptedException {
		//下发工单
		//维护人员的电话号码
		String maintenancePhone = repairV.getMaintenancePhone();
		AppUserV appUser = appUserService.getAppUserByPhone(maintenancePhone);

		long channelId = appUser.getPushChannelId();
		String userId = appUser.getPushUserId();
		String msgTitle = "自动派发工单";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String msgDesc = "自动派发工单,机器序列号："+ repairV.getSerialNumber();
		if(repairV.getExpectedRepairTime() != null){
            msgDesc += ",期望维修时间:"+sdf.format(repairV.getExpectedRepairTime());
        }
        WxUserV wxUser = wxUserService.getByMobilePhone(repairV.getBankUserPhone());
		Map<String, String> msgCustomMap = new HashMap<String, String>();
		String url = Constants.SERVER_HOST + "/weixin/repair/select/"+repairV.getId();
		if(wxUser!=null && !Utils.isEmpty(wxUser.getOpenId())){
			url += "?openId="+wxUser.getOpenId();
		}else{
			url += "?openId="+Constants.DEFAULT_OPEN_ID;
		}
		msgCustomMap.put("req", url);
		msgCustomMap.put("repairId", String.valueOf(repairV.getId()));
		//先APP推送，记录推送结果，总共重试3次，间隔30秒
    	int count = 0;
    	boolean sendFlag = false;
    	
    	//修改工单状态:先改状态为已派发，失败了再改回未派发，防止跟自动派发重复派单
	    repairV.setStatus(WorkStatus.DISTRIBUTE.getValue());
	    repairService.saveRepair(repairV);
	    
    	while(count<3 && !sendFlag) {
    		if(appUser.getDeviceType()==1) {
    			sendFlag = AndroidPushNotification.pushMsg(channelId, userId, msgTitle, msgDesc, msgCustomMap);
    		}else {
    			sendFlag = IosPushNotification.pushMsg(channelId, userId, msgTitle, msgDesc, msgCustomMap);
    		}
    		if (sendFlag) {
    			break;
    		} else {
        		count++;
        		logger.info("第{"+count+"}次推送失败");
        		Thread.sleep(30000);
    		}
    	}
    	ResultModel rm = new ResultModel();
    	//如果推送失败，记录一条失败记录，产生一个系统提醒
    	if(!sendFlag) {
    		logger.info("推送失败,尝试推送次数{"+count+"}");
    		//派发失败，改回状态:未派发
			repairV.setStatus(WorkStatus.NEW.getValue());
		    rm = repairService.saveRepair(repairV);
    		rm.setFailCode();
    	}else {
    		logger.info("推送已成功,推送次数{"+count+"}");
            rm.setSuccessCode();
    	}
    	//记录推送结果
		AppPushLogV appPushLogV = new AppPushLogV();
		appPushLogV.setChannelId(String.valueOf(channelId));
		appPushLogV.setUserId(userId);
		appPushLogV.setMsgTitle(msgTitle);
		appPushLogV.setMsgDesc(msgDesc + " --- " + repairV.getFaultInfo());
		appPushLogV.setUrl(url);
		appPushLogV.setStatusCode(rm.getStatusCode());
		appPushLogService.saveAppPushLog(appPushLogV);	
	}


}
